/**
 * @file sentiment_analysis.hpp
 * @brief 情感分析系统核心头文件
 * @author Zeal Cmixed
 *
 * 该文件定义了情感分析系统所需的核心数据结构、枚举和类：
 * - 性别、情感类型等枚举定义
 * - 用户输入、情感结果等数据结构
 * - 情感判断准则格式定义
 * - EmoJC(情感判断准则)和SentiAnal(情感分析)类
 * - JSON序列化/反序列化函数声明
 */

#ifndef SENTIMENT_ANALYSIS_HPP
#define SENTIMENT_ANALYSIS_HPP

#include "pch.hpp"
#include "include/json.hpp"

namespace sal {

    using json = nlohmann::json;  ///< JSON类型别名

    /**
     * @enum Gender
     * @brief 性别枚举
     */
    enum class Gender {
        MALE = 0,    ///< 男性
        FEMALE,      ///< 女性
        UNKNOWN      ///< 未知性别
    };

    /**
     * @struct UserInput
     * @brief 用户输入数据结构
     *
     * 存储从JSON文件解析的用户生理数据
     */
    struct UserInput {
        std::string ID;                  ///< 用户唯一标识
        Gender gender;                   ///< 用户性别
        std::uint32_t age;               ///< 用户年龄
        std::uint32_t heartRate;         ///< 心率(次/分)
        std::uint32_t respiratoryRate;   ///< 呼吸频率(次/分)
        std::uint32_t bloodPressure;     ///< 血压(毫米汞柱)
    };

    /**
     * @enum EmoT
     * @brief 情感类型枚举
     */
    enum class EmoT : std::int_fast8_t {
        POSITIVE = 0,   ///< 积极情感
        NEGATIVE,       ///< 消极情感
        NEUTRAL,        ///< 中性情感
        UNKNOWN         ///< 未知情感状态
    };

    /**
     * @struct EmoRes
     * @brief 情感分析结果
     */
    struct EmoRes {
        std::string ID{};           ///< 用户唯一标识
        EmoT type{EmoT::UNKNOWN};   ///< 情感类型
    };

    /**
     * @struct EmoJCFB
     * @brief 情感判断基础准则
     *
     * 包含单个情感类型对应的生理指标范围
     */
    struct EmoJCFB {
        std::pair<std::uint32_t, std::uint32_t> heartRate{};         ///< 心率范围(次/分)
        std::pair<std::uint32_t, std::uint32_t> respiratoryRate{};   ///< 呼吸频率范围(次/分)
        std::pair<std::uint32_t, std::uint32_t> bloodPressure{};     ///< 血压范围(毫米汞柱)

        /// 默认构造函数
        EmoJCFB() = default;

        /**
         * @brief 带参数构造函数
         * @param hr 心率范围
         * @param rr 呼吸频率范围
         * @param bp 血压范围
         */
        EmoJCFB(std::pair<std::uint32_t, std::uint32_t> hr,
                std::pair<std::uint32_t, std::uint32_t> rr,
                std::pair<std::uint32_t, std::uint32_t> bp)
            : heartRate(hr), respiratoryRate(rr), bloodPressure(bp) {}
    };

    /**
     * @struct EmoJCF
     * @brief 完整的情感判断准则
     *
     * 包含特定性别和年龄范围的完整情感判断标准
     */
    struct EmoJCF {
        Gender gender{Gender::UNKNOWN};                              ///< 适用性别
        std::pair<std::uint32_t, std::uint32_t> age{};               ///< 适用年龄范围
        std::array<std::pair<EmoT, EmoJCFB>, 3> criteria{};          ///< 三种情感类型对应的生理指标范围
    };

    /**
     * @class EmoJC
     * @brief 情感判断准则类
     *
     * 负责加载、存储和查询情感判断准则
     */
    class EmoJC {
    public:
        std::map<std::pair<Gender, std::uint32_t>, std::unique_ptr<EmoJCF>> m_jdmCri{};  ///< 存储情感判断准则的映射表
        std::optional<UserInput> m_currentUser;  ///< 当前处理的用户数据

        /**
         * @brief 查找匹配的评判标准
         * @param gender 用户性别
         * @param age 用户年龄
         * @return 匹配的EmoJCF对象或错误
         */
        auto findJudgementCriteria(Gender gender, uint32_t age) -> std::expected<EmoJCF, std::error_code>;

        /**
         * @brief 执行情感判断
         * @param jcf 已找到的评判标准
         * @return 情感类型或错误
         */
        [[nodiscard]] auto judgementCriteria(const EmoJCF& jcf) const
            -> std::expected<EmoT, std::error_code>;

        /**
         * @brief 从文件加载情感判断准则
         * @param filename JSON文件路径
         * @return 操作结果或错误
         */
        auto fileInput(const std::string& filename) -> std::expected<std::string, std::error_code>;
    };

    /**
     * @class SentiAnal
     * @brief 情感分析类
     *
     * 负责加载用户数据、执行情感分析和输出结果
     */
    class SentiAnal {
    public:
        std::map<std::string, EmoRes> m_res;        ///< 情感分析结果集合
        std::optional<UserInput> m_currentUser;      ///< 当前处理的用户数据

        /**
         * @brief 从文件加载用户数据
         * @param filename JSON文件路径
         * @return 操作结果或错误
         */
        [[nodiscard]] auto fileInput(const std::string& filename)
        -> std::expected<std::string, std::error_code>;

        /**
         * @brief 执行情感分析
         * @param emoJC 已加载的情感判断准则对象
         * @return 操作结果或错误
         */
        [[nodiscard]] auto analysis(EmoJC& emoJC)
        -> std::expected<std::string, std::error_code>;

        /**
         * @brief 输出分析结果
         * @return 操作结果或错误
         *
         * 输出到终端和output.md文件
         */
        [[nodiscard]] auto messageOutput() const
        -> std::expected<std::string, std::error_code>;
    };

    // JSON 序列化和反序列化函数声明
    void to_json(json& j, const EmoJCFB& emoJCFB);
    void from_json(const nlohmann::json& j, EmoJCFB& emoJCFB);
    void to_json(json& j, const EmoJCF& emoJCF);
    void from_json(const nlohmann::json& j, EmoJCF& emoJCF);
    void to_json(json& j, const UserInput& userInput);
    void from_json(const json& j, UserInput& userInput);

} // namespace sal

#endif // SENTIMENT_ANALYSIS_HPP
